Я так и сделал, не получалось потому, что надо два заклинания делать....
Один буферизуется другой нет... Еще один вопрос по теме, что значит буферизуется\не буферизуется? И можно тему закрывать.
quq_CCCP, Ну я на хайве видел полуджассовый вампиризм. Так мне и нужно вручать при замахе, чтоб если героя диспелят он вампиризм при атаке вернул. А утечку показывает, как я атакую, сразу хендл на один повышается. Может руна не удаляется? ClotPh, Вообще не понял о чём ты.
Решил проблему, утечка возникала из -за не удаления руны, она почему-то не удаляется изнутри триггера, создал отдельный для удаления и нет утечки.
И в чём смысл делать глобалку, а не просто писать тогда уж сразу GetFilterUnit( )
Я сдеал локалку, чтобы вместо GetFilterUnit( ) писать то, что мне нужно, в данном случае CLONE quq_CCCP:
Потом клонов от способностей ищут не так,
Да так и я их могу найти
Точнее не совсем так, я их искал через Юнит входит в Область ( Игровая зона )
Но искать их в другом триггере и сдругим событием мне нафиг не нужно.
Мне нужно найти иллюзии сразу в триггере со способностью, чтобы потом не было геморроя
========================
И ещё раз повторюсь, что при повторном использовании способности, 2 прошлые иллюзии (да и вообще в принципе если рядом с гером будут другое любое ко-во иллюзий) перемещаются к противнику. Но две новосозданные остаются на месте.
Так же повторюсь, что когда проверка была IsUnitIllusion == false, то иллюзии определяло как не иллюзии!
Все кто пытались помочь, похоже проигнорировали это замечание...
========================
Мой вывод таков: Иллюзиям, призванным через стандартную Способность (Предмет: Иллюзии) присваивается статус иллюзий слегка позже, чем происходит проверка.
С другой стороны, скорее всего это может и можно как-то обойти, ведь есть карты примеры, где подобное работает нужным образом.
О том, как устроены чёртовы способности близов стоит только догадываться =\
К счастью Способность (Предмет: Иллюзии) не наносит 0.00 урона, и за это близам огромное спасибо (что у меня в очередной раз не бомбануло)
А вообще, проще по-моему сделать свою игру, чем нормальную карту в варкрафте -_-
че-то действительно, поле вроде бы и отображает активную атаку, но не является её определителем, т.е. менять его бесполезно. ок, тогда пока нет решения на мх
Дальше пришла в голову другая идея. Думаю, можно сделать с помощью ремонта зданий Альянса: на месте смерти героя создаётся здание с моделью креста со здоровьем 1/100 ед., а союзные герои ремонтируя крест будут повышать её здоровье, получается некая иллюзия прогресс бара. И если спрятать способность ремонта с помощью функции HideAbilityButton( ) из мемхака, то будет ли она срабатывать при нажатии на ПКМ? Также, как отловить момент полного ремонта здания? С помощью таймера проверять процент здоровья каждые доли секунды?
раскрыть
scope HeroRevive initializer Initialization
struct herorevive
private unit dyingUnit
private unit reincarnate
private real life
private thistype prev
private thistype next
public static constant trigger trig = CreateTrigger( )
public static constant timer period = CreateTimer( )
private static method iterate takes nothing returns nothing
local thistype this = thistype( 0 ).next
loop
exitwhen ( this == 0 )
if ( GetWidgetLife( this.reincarnate ) > this.life ) then
set this.life = GetWidgetLife( this.reincarnate )
elseif ( GetWidgetLife( this.reincarnate ) >= GetUnitState( this.reincarnate, UNIT_STATE_MAX_LIFE ) ) then
call ReviveHero( this.dyingUnit, GetUnitX( this.dyingUnit ), GetUnitY( this.dyingUnit ), true )
call RemoveUnit( this.reincarnate )
set this.reincarnate = null
set this.life = 0.0
set this.prev.next = this.next
set this.next.prev = this.prev
if ( thistype( 0 ).next == 0 ) then
call PauseTimer( thistype.period )
endif
call thistype.deallocate( this )
elseif ( GetWidgetLife( this.reincarnate ) <= this.life ) then
set this.life = 1.0
call SetWidgetLife( this.reincarnate, this.life )
endif
set this = this.next
endloop
endmethod
public static method actions takes nothing returns nothing
local thistype this = thistype.allocate( )
set this.next = 0
set this.prev = thistype( 0 ).prev
set this.next.prev = this
set this.prev.next = this
set this.dyingUnit = GetDyingUnit( )
set this.reincarnate = CreateUnit( GetOwningPlayer( this.dyingUnit ), 'h003', GetUnitX( this.dyingUnit ), GetUnitY( this.dyingUnit ), 0.0 )
set this.life = 1.0
call SetUnitPathing( this.reincarnate, false )
call SetWidgetLife( this.reincarnate, this.life )
if ( this.prev == 0 ) then
call TimerStart( thistype.period, 0.10, true, function thistype.iterate )
endif
endmethod
public static constant method conditions takes nothing returns boolean
return IsUnitType( GetDyingUnit( ), UNIT_TYPE_HERO )
endmethod
endstruct
public function Initialization takes nothing returns nothing
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 1 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 2 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 3 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 4 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerAddCondition( herorevive.trig, Condition( function herorevive.conditions ) )
call TriggerAddAction( herorevive.trig, function herorevive.actions )
endfunction
endscope
Вот только если спрятать кнопку через HideAbilityButton( ), то способность ремонта зданий исчезает и не работает через ПКМ.
RMem/WMem - вторая версия, есть еще третья и, скорее всего, последняя
function SetAbilityStringParam2 takes integer id, integer off, string newVal, integer lvl returns boolean
local integer k=GetAbilityUIDefCaching(id)
if k < 1 then
return false
endif
set k=k+off
set k=RMem(k)
if k>0 then
set k=k+lvl*4-4
call AddNewOffsetToRestoreFast(k)
call WMem(k,GetStringAddress(newVal))
return true
endif
return false
endfunction
скорее всего ты при инициализации проверяешь статус слота игрока, а этого делать нини ))) ибо это частенько может приводить к десинку, вот эти игроки и получают его благополучно во время инициализации)))
Ну можно по-разному. Главное понять от чего отталкиваться.
Создаем две переменные: одна целочисленная К и вторая целочисленная G с массивом.
событие - инициализация
действие - цикл А от 1 до 6 //это игроки 1-6 -=1 клан или можно от 1-3, у тебя же 3 первых игрока
if игрок (A) = комп and игрок (А) = играет then
К=К+1 //кол-во игроков
G (К) = А //номер игрока, в этой ячейке хранится номер игрока
endif
также можно было создать группу игроков, и при инициализации засунуть и использовать ее, но не важно.
Вызываем
I=Random (от 0 до К) //короче I - это целочисленная переменная, К - общее кол-во игроков
И передать здания Игрока Х игроку ( G (I) )
Артес Менетил, для начал в задницу яндекс - трешак еще тот, используй гугл. А дальше слушай, напрямую конвертера в MDX с дренора не существует, Импортируй M2 в макс скриптом, потом экспортируй в MDX и используй, экспортировать можешь скрипом экспорта в MDX и вручную добавить материалы в W3ME. Оба скрипта есть на сайте, если тебе нужны юниты с анимациями - тут нужно с бубном поплясать и методами, которых я не знаю, либо скачать плагин NeoDex с хайва и экспортировать через него со всеми прекрасностями, но там тоже нужно будет настраивать, читай гайды на том же хайве, только учти, что они все не на русском
Извлечь м2 можешь программами работающими с новым форматом архивов CASCExplorer или CASCViewer
UniverseRuler, в доте 6-6 использованы игроки 13 и 14
тебе нужно просто сохранять приказ отданный триггерно(ты ведь ими будешь юнитами управлять)
и восстанавливать его при получение приказа для игрока
для этого нужна буленовская переменная для определения триггерный это приказ или нет
и структура/хэш/юзердата для сохранения приказа UniverseRuler:
еще остались асы картостроения, но а сейчас начинаю думать, что их все таки нету
если ас картостроения это человек который воплощает все ваши фантазии в жизнь то тут таких нету и не было
ещё можно создавать всех юнитов за 1 резервного игрока
а автоатаку делать триггерно
этот вариант самый лучший но то просто не сможешь его сделать
ибо нужны джасс+алгоритмы+структуры/хэш
а ты судя по всему ничего из этого не знаешь
делаем спелл на основе канала
при применении этого спелла выбираем всех юнитов в радиусе R от юнита применившего спелл и имеющих того же владельца что и юнит применивший заклинания
и переносим их в точку каста
где R это радиус захвата юнитов для телепортации
спецэффекты по вкусу
это если массовая телепортация (герой + юниты рядом с ним)
если только герой то как сказали выше
Каждый раз по прошествии этого самого определённого промежутка времени пикаешь (Отряд - Pick Every units...) нужных (всех?) тебе юнитов, при условии что они находятся в нужной области, а после мгновенно перемещаешь в другую область.
Таймер кончается, все герои которые не находятся на арене - телепортируются на неё. В это же время в области создаётся нужное количество мобов и мегамоб(босс).
Окончание раунда, точно ещё не разобрался
Делаешь, наверное, неправильно. Сначала тебе нужно выделить те декорации (копировать, вырезать), потом жмешь вставить (у тебя появится возможность выбрать место, куда ты их хочешь поставить, будут видны сами объекты, которые двигаются за курсором мыши). После этого ничего не жмешь и идешь в пункт Правка и жмешь Повернуть.../Отразить..., как тебе нужно, и только после всего этого ставишь на карту повернутый вариант.
bOrissko, Почти, я создавал карту на рабочем столе а оказалось что менять тайлсеты можно только в папке maps. Но сделать обрыв в бездну и обрыв затонувшего города так и не получилось(
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил. nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath
globals
mhook ahook[100]
integer ihook = -1
endglobals
struct mhook
unit host = null
unit target = null
real face = 0
real speed = 0
real dis = 0
real dismax = 0
integer chaini = 0
unit chain[50]
real scale = 0
integer move = 1
integer i = 0
static method Create takes unit host, real tx, real ty, real scale returns mhook
local mhook h = mhook.create()
local integer i = GetPlayerId(GetOwningPlayer(host))
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real f = GetAngleXY(x,y,tx,ty)
set h.host = host
set h.face = f
set h.speed = 600
set h.dismax = 1400
set h.scale = scale
set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
set h.i = i
call UnitAddAbility(h.chain[0],'Amrf')
call UnitAddAbility(h.chain[0],'Amrf')
call SetUnitFlyHeight(h.chain[0],50,0)
call SetUnitPathing(h.chain[0],false)
return h
endmethod
method Start takes nothing returns boolean
if ihook < 1000 then
set ihook = ihook + 1
set ahook[ihook] = this
return true
else
return false
endif
endmethod
method Destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > ihook
if ahook[i] == this then
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = ihook // выход из цикла
endif
set i = i + 1
endloop
set this.target = null
set this.host = null
call this.destroy()
endmethod
method Move takes nothing returns nothing
local integer i1 = 0
local integer l = 0
local real x
local real y
local real xh
local real yh
local real f
if move == 1
set dis = dis + speed*0.025
loop
exitwhen i1 > .chaini
set x = GetUnitX(.chain[i1])
set y = GetUnitY(.chain[i1])
if i1 > 0 then
set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
else
set f = face
call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
endif
call SetUnitFacing(chain[i1],f)
set i1 = i1 + 1
endloop
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
//Create==================
if GetDisXY(xh,yh,x,y) >= .scale/2 then
set chaini = chaini + 1
set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
call UnitAddAbility(.chain[.chaini],'Amrf')
call UnitAddAbility(.chain[.chaini],'Amrf')
call SetUnitFlyHeight(.chain[.chaini],50,0)
endif
if dis > dismax then
set move = 0
endif
else
//REVERSE=============
set xh = GetUnitX(host)
set yh = GetUnitY(host)
set chain[chaini+1] = host
loop
exitwhen l > chaini
set x = GetUnitX(chain[l])
set y = GetUnitY(chain[l])
//if chain[chaini] == null then
// set f = GetAngleXY()
//endif
set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
call SetUnitFacing(chain[l],f-180)
set l = l + 1
endloop
//Destroy==================
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set xh = GetUnitX(host)
set yh = GetUnitY(host)
if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
call RemoveUnit(chain[chaini])
set chain[chaini] = null
set chaini = chaini - 1
if chaini == -1 then
call .Destroy()
endif
endif
endif
endmethod
endstruct
private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t
loop
exitwhen i > ihook
if ahook[i] != 0 then
set h = ahook[i]
//--run--//
call h.Move()
else
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = i - 1
endif
set i = i + 1
endloop
//call DestroyGroup(g)
set g = null
set t = null
endfunction
function Trig_HookC_Bool takes nothing returns boolean
if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
return true
else
return false
endif
endfunction
function Trig_HookC_Actions takes nothing returns nothing
local mhook h
set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
call h.Start()
endfunction
function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function Trig_HookC_Actions )
call TriggerAddCondition(t,function Trig_HookC_Bool)
call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction
endlibrary
А если создать дамми-юнитов каждого типа? Попробуй как-то так: Триггер 1
Событие - Игрок выбрал юнита
Условие - Триггерный игрок не равен игроку-владельцу триггерного юнита
Действие:
Записать триггерного юнита в переменную из массива U[номер триггерного игрока];
сменить владельца юнита-дамми (можно через базу данных сделать и вычислять по типу выбранного юнита) на триггерного игрока;
выбрать юнита-дамми для триггерного игрока;
установить юниту-дамми Custom Value = номеру триггерного игрока Триггер 2
Событие - Юнит получил приказ без цели
Условие - Custom Value триггерного юнита больше 0
Действие - Приказать юниту U[Custom Value триггерного юнита] выполнить приказ ("полученный приказ") Триггер 3
Событие - Игрок отменяет выбор юнита
Условие - Custom Value триггерного юнита больше 0
Действие - Установить триггерному юниту Custom Value = 0
Ещё можно сделать дамми-юнитов зданиями с набором только тех способностей, которые можно активировать.
P.S. Есть один недостаток у этой системы - кулдаун способностей. Не знаю, как его синхронизировать. Разве что делать дамми для каждого конкретного юнита или использовать мемхак. Но если автор умеет его использовать, то это он мне советы давать должен, а не наоборот =)
Drulia_san, Ну да.
Добавляешь аурку - вот тебе баф на юните. Самый простой способ как по мне.
+Можно эффекты настроить, что вполне неплохо. Пока висит фейковый баф(наша аура) - на юните есть эффект.
Через дамми касты я пробовал, но долго+муторно+подключается дамми система = +лаги и местами утечки.
Насчёт таймаута - это уже по самим спеллам, я долго мучался чтобы оно всё работало как надо и не оверлапалось
Вот такой штукой у меня удаляется баф:
public function unitRemoveAbilityandBuffBY(unit u,integer dhv,integer mLv) returns boolean
boolean b=UnitRemoveAbility(u,dhv)
UnitMakeAbilityPermanent(u,false,dhv)
UnitRemoveAbility(u,mLv)
return b
]]Chupakabra[[, я понял. Крч на костылях придется лепить. Попробуй при выборе героя добавлять геройские абилки, а потом блочить или удалять их. Думаю, так можно добавить до 7 штук. Через ро не получается больше 5.
Если не получится - пробуй делать полностью триггерно с помощью спеллбука.
PT153, это лимит для одного игрока, то есть героя смогут нанять другие.
Нужно поставить таверне способность Продажа войск. Потом делаешь триггер:
Событие: Юнит вошёл в область (Вся игровая карта)
Условие: Триггеринг юнит равно Герой равно Да (можно этого не делать, просто исключает срабатывание триггера для каждого юнита)
Действия: несколько действий Если/То/Иначе
Если - Юнит тип (Триггеринг юнит) равно Какой-то Герой Из Таверны
То - Нейтральное здание - Удалить Какой-то Герой Из Таверны из таверны
Иначе - Ничего
И так для каждого типа героев в таверне.
Условие - твой герой имеет в статусе баф от нужной способности (можно сделать на базе Жара прейсподней с нулевыми параметрами)
Действие - Проверяем есть ли у героя необходимая мана - если да - то продолжать цикл, если нет - давать приказ - выключить твою способность. Создавать дамми-юнита __(в виде огненного шара к примеру)__и на большой скорости запускать его в направлении куда сморит герой, плюс минус 5 градусов. Давать даммику таймер уничтожения где-то 0.2-0.4 секунды, его можно повышать с уровнем способности - так огненное дыхание будет дальше при вкачивании.
Получается что в секунду триггер будет выпускать 20-25 огненных шаров с небольшими попровками на углу движения - в результате эффект огненной волны, получится и красиво и здорово.
Конечно нужно еще создать триггер, который будет отлавливать налетел ли на кого-то твой огненный шар - и наносить урон.
Кстати только потом подумал)) можно не заморачиваться насчет затрат маны и её пересчета. Можно прямо в способности жара прейсподней поставить затраты на применение и кастование, в триггере можно условия эти убрать.
может скинешь карту удали все что не связанно с предметами посмотрим что не так.
Вот скрин одного из предметов, который перестал работать. Boots of Travel - активка. Мне кажется это просто баг, так как перестает работать какой-то предмет, на самом деле, очень редко. Я думал может есть какое то логическое объяснение, но увы.
Спасибо за ответы.
Делай мвссив с индексом равным номеру игрока (чтоб не запутаться) При событии ставь условие на триггеринг игрока. Если триггенинг игрок = красный то перекидывай соотв. юнита по индексу. напр MyHero[1]. Используй if then else. Все вместится в 1 триггер с кол-вом событий равным кол-ву игроков.
первое без триггеров не убрать, нужно создать условие, где изучаено исследование, и действие где ты выполняешь над юнитом действие, удалить способность.
НА счет второго, есть такое исследование, по мойму называется "темный", из первой части 3 варика. в его параметрах указываешь войско и на какие меняются, ну и уже его пихаешь в домик и изучаешь
ТЬФУ! Никто, начиная с меня, JASS читать не умеет!
call SetAbilityCD (GetSpellAbilityId(), i, GetAbilityCD(GetSpellAbilityId(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())) * percent)
на русский переводится как:
Задать перезарядку способности (Кастуемая способность, уровень i, получить перезарядку способности юнита на ТЕКУЩЕМ УРОВНЕ СПОСОБНОСТИ ЮНИТА и умножить на нашу переменную)
Какого хрена тут ТЕКУЩИЙ УРОВЕНЬ, когда должен тоже быть уровень i?! Оно в цикле везде берет текущий уровень абилки вмеcто i. Т. е. если перезарядка на разных уровнях разная, это уже ппц ошибка.
Сейчас как раз фикшу эту абилу, она один хрен не до конца правильно действует, и уже тут самые разные извращения с ней получались, после выхода из вара фаталило, крч, 90% вероятности, что другие абилы Психопомпы в поряде, а фатал здесь.
Короче, вот, вроде теперь действует нормально.
Извините уж, что не под катом, мозги уже не имеют сил кат вставлять.
function BendingEffect takes nothing returns nothing
local real percent = 1.00
local real percent2 = 0.00
local integer i = 11
local integer percentchange = 0
if ( GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) >= 1 ) and (GetAbilityCD(GetSpellAbilityId(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())) >= 1) then
УВЕЛИЧЕНИЕ НА 1%
if UnitHasBuffBJ(GetTriggerUnit(),'B0H8') == true then
set percent = 1.01
endif НА 1% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 2%
if UnitHasBuffBJ(GetTriggerUnit(),'B0H9') == true then
set percent = 1.02
endif НА 2% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 3%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HA') == true then
set percent = 1.03
endif НА 3% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 4%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HB') == true then
set percent = 1.04
endif НА 4% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 5%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HC') == true then
set percent = 1.05
endif НА 5% - ЗАКРЫТО.
ТАЛАНТ СИЛЬНОЕ ИСКРИВЛЕНИЕ
set i = 0
set percent = percent - 1
loop
set i = i + 1
exitwhen i > 12
if ( GetUnitAbilityLevelSwapped('A281', udg_Circle[i]) == 2 ) then
set percent = percent * 2
set i = 12
endif
endloop
set percent = percent + 1 ТАЛАНТ СИЛЬНОЕ ИСКРИВЛЕНИЕ - ЗАКРЫТО.
ОКРУГЛЕНИЕ ДО СОТЫХ (ИНАЧЕ МОГУТ ЗАПИСАТЬСЯ ДОП. ЦИФРЫ НЕ В ТЕ ЯЧЕЙКИ)
loop
exitwhen i < 1
set i=i - 1
set percent2 = GetAbilityCD(GetSpellAbilityId(), i) * percent
set percent2 = percent2 * 100
set percentchange = R2I(percent2)
set percent2 = I2R(percentchange)
set percent2 = percent2 * 0.01
call SetAbilityCD(GetSpellAbilityId() , i , percent2)
endloop
ОКРУГЛЕНИЕ ДО СОТЫХ - ЗАКРЫТО.
endloop
else
endif
else
endif
endfunction
//////////////
Ну, короче, действует-то однозначно она уже лучше, раньше цифры высчитывались с избытком, теперь явно правильнее. Насчет фаталов время покажет... Но все равно стало лучше.
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
дать труповозке кастом велью (или свою переменную, если труповозок больше чем 1 - массив с индеком или опять кастом велью) по количеству трупов не? если ты используешь гулей как боевые единицы, создай их кастомную копию и используй её, а появление натурального гуля (или его трупа) уже отлавливай Maxim53:
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
собсно, порывшись в редакторе, есть идея насчет выброски трупа - дать труповозке запрещенный спеллбук со стандратным скиллом Drop Corpse и дать приказ на его каст, как только прокастует - дать команду Stop, чтобы больше 1 трупа не вылетело. И я не знаю как отследить выброшенный труп, потому что его нужно будет сразу удалить из игры, а если трупов в округе больше 1 - конкретно выброшенный твоей труповозкой отследить не представляется мне возможным Maxim53:
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
можешь дать труповозке ману без регена, и скилл наподобие того что у гулей (я...ням-ням..кушать....людей), когда они едят трупы, и за каждый съеденный давать 1 ману, а при касте - тратить или сразу манакост в 1 выставить. Если у тебя есть восстановители маны - опять таки вводить массив\кастом велью по количеству трупов и периодически устанавливать ману в его значение, но это немного бажно, ибо становится возможен каст без наличия трупа. Obelick:
Что? Какое заклинание? Ты не написал, что именно тебе надо. Ты хочешь сделать заклинание труповозки триггерно? Или что? Трупы в ней - это вурдулаки, загруженные как на корабль. Выбрать трупы тоже можно, есть где-то в условиях.
выбрать трупы внутри труповозки нельзя, насколько я сейчас понял. даже если внести всех жмуриков на карте в массив - у труповозки есть способность Exnum Corpses, когда она сама генерирует труп. Причем он не появляется рядом и она его поднимает, он сразу добавляется ей. Как их-то отловить? Только если выкинуть
Да, можно. Если знаешь как правильно выстроить случайное значение, то особого труда не составит построить определенный сценарий. Это можно реализовать через области, 3 изначальные области где будет выстраиваться тот или иной сценарий + через математический расчет координат областей можно выставить определенные предметы, но краше будет чистый "hardcore", выстраиваем случайное расположение точек, и в них что угодно, магазин, декор, и так далее...
На практике выглядит так:
При прогрузке карты выдаем случайное значение, которое имеет... скажем 3 триггера (3 комнаты). И в триггерах прописываем сценарий рендера локации комнаты, плюс триггер на эффект обитателя в области той или иной комнате.
Что за чушь ты тут описал? Просто когда спасатели прилетают, паузи таймер, а при перезапуске игры, запускай его по новой(с тем же ожиданием)
Кстати, идея норм. Можешь скинуть? А то я не удержусь, и стырю её у тебя :D
Нашёл систему, где звук передаётся в таймер, который истекает через 0 секунд. В результате один и тот же звук может проигрываться несколько раз без всяких проблем. В инетике пишут мол это такой баг движка.
Только дебаффы ядовитых стрел могут стакатся, но даммик обязан иметь дальнюю атаку (при условии что у разных абилок ядовитых стрел будут разные баффы в настройках).
Так же можно юзать таймер и ауру торнадо как написали выше, ну если уж совсем нужен сложный бафф как дефолтный - то тут триггер и немного гемора с мемхаком, зато полный комплект параметров (мигает иконка в статусе перед завершением время действия, бафф спадает с цели после диспела, смерти (у цели крест перерождения или аналог), складывается или не складывается в зависимости от кода).
Пример не рекомендуемый к повторению
function FormatAirportTrainingBar takes integer fp_n returns string
local string str = ""
if ( fp_n <= 0 ) then
return str
endif
loop
exitwhen fp_n < 10
if ( udg__TempBarStyle == 0 ) then
set str = str + "''''''''''"
else
set str = str + "||||||||||||||||||||"
endif
set fp_n = fp_n - 10
endloop
loop
exitwhen fp_n <= 0
if ( udg__TempBarStyle == 0 ) then
set str = str + "'"
else
set str = str + "||"
endif
set fp_n = fp_n - 1
endloop
return str
endfunction
function UpdateAirportTrainingBar takes texttag tt, integer fp_nTick, integer fp_nTickMax returns nothing
local integer nProgress
local integer nLen
local string strTT1
local string strTT2
if ( tt == null ) then
call BJDebugMsg( "text tag hDZzRwuZxFQcXqaMPnML null" )
return
endif
set nLen = R2I( I2R( fp_nTickMax ) / 300 * 100 )
set nProgress = R2I( I2R( nLen ) / fp_nTickMax * fp_nTick )
set strTT1 = "" + FormatAirportTrainingBar( nProgress )
set strTT2 = FormatAirportTrainingBar( nLen - nProgress ) + ""
call SetTextTagText( tt, "|cff0080c0" + strTT1 + "|r|cffff0000" + strTT2 + "|r", 0.023 )
endfunction
function Get_Staff_of_Purification takes unit runner returns item
set bj_forLoopAIndex = 0
set bj_lastCreatedItem = null
if GetUnitAbilityLevel( runner, 'Arun' ) == 0 then
return null
endif
loop
exitwhen bj_forLoopAIndex > 5
set bj_lastCreatedItem = UnitItemInSlot( runner, bj_forLoopAIndex )
if GetItemTypeId( bj_lastCreatedItem ) == 'I01A' then
return bj_lastCreatedItem
endif
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
return bj_lastCreatedItem
endfunction
function Trig_RunnerDamageDetect_Conditions takes nothing returns boolean
if GetTriggerEventId( ) == EVENT_UNIT_DAMAGED then
return GetEventDamage( ) > 0.00 and GetEventDamageSource( ) != GetTriggerUnit( ) and GetEventDamageSource( ) != DummyAttacker
endif
return true
endfunction
function HealRunner takes nothing returns nothing
local DamageData dd = GetDataBX( GetExpiredTimer( ) )
call UnitRemoveAbility( dd.attacked, 'AMhp' )
call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp )
call RemoveDataBX( dd.trix )
call DestroyTimer( dd.trix )
call dd.clear( )
call dd.destroy( )
endfunction
function Trig_RunnerDamageLock_Actions takes nothing returns nothing
local TriggerData st = GetDataBX( GetTriggeringTrigger( ) )
local DamageData dd
local eventid id = GetTriggerEventId( )
if id == EVENT_GAME_TIMER_EXPIRED and st.id < st.time and st.attacked != null then
set st.id = st.id + 1
if GetUnitAbilityLevel( st.attacked, 'Bcyc' ) > 0 or GetUnitAbilityLevel( st.attacked, 'Bcy2' ) > 0 then
call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 585.00 )
else
call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 80.00 + GetUnitFlyHeight( st.attacked ) )
endif
call UpdateAirportTrainingBar( st.tt, 100 - R2I( st.dmg / st.hp * 100.00 ), 100 )
elseif id == EVENT_UNIT_DAMAGED and st.dmg < st.hp then
set dd = DamageData.create( )
set dd.trix = CreateTimer( )
set dd.attacked = st.attacked
set dd.dmg = GetEventDamage( )
set dd.hp = GetUnitState( dd.attacked, UNIT_STATE_LIFE )
call SetDataBX( dd.trix, dd )
call UnitAddAbility( dd.attacked, 'AMhp' )
call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp + dd.dmg )
call TimerStart( dd.trix, 0.00, false, function HealRunner )
set st.dmg = st.dmg + dd.dmg
else
call UnitRemoveAbility( st.attacked, 'A08L' )
call UnitMakeAbilityPermanent( st.attacked, false, 'A08L' )
call DisableTrigger( st.trg )
call SetTextTagVisibility( st.tt, false )
if not IsUnitDead( st.attacked ) then
call UnitRemoveAbility( st.attacked, 'B00A' )
endif
call RemoveSavedInteger( gg_htb_HashData, ExKeySoPRunner, GetHandleId( st.attacked ) )
call st.RemoveTrigger( )
call st.destroy( )
endif
set id = null
endfunction
function Trig_Staff_of_Purification_Actions takes nothing returns nothing
local TriggerData dd
local unit Runner = GetSpellAbilityUnit( )
local integer RunnerId = GetHandleId( Runner )
local item Staff = LoadItemHandle( gg_htb_HashData, RunnerId, ExKeySoP )
local integer ChargesCount = 0
local trigger trig = LoadTriggerHandle ( gg_htb_HashData, ExAtomShield, RunnerId )
local integer pBuff
if Staff == null then
set Staff = Get_Staff_of_Purification( Runner )
if Staff == null then
//call DisplayTextToPlayer( Player( CrashPlayerNumber ), 0.00, 0.00, I2Sx( 'A01Q', CrashPlayerNumber ) )
call BJDebugMsg( DEBUG + I2Sx( 'A02O', 0 ) + INFO )
return
endif
call SaveBoolean( gg_htb_HashData, RunnerId, ExKeyHasStaff, true )
call SaveItemHandle( gg_htb_HashData, RunnerId, ExKeySoP, Staff )
endif
set ChargesCount = GetItemCharges( Staff )
if ChargesCount < 1 then
set Runner = null
set Staff = null
set trig = null
return
endif
call SetItemCharges( Staff, 0 )
if trig != null then // блокирующие урон способности не складываются.
call TriggerExecute( trig )
set trig = null
endif
set dd = TriggerData.create( )
set dd.attacked = Runner
set dd.pl = GetOwningPlayer( Runner )
set dd.trg = CreateTrigger( )
set dd.trc = TriggerAddCondition( dd.trg, Condition( function Trig_RunnerDamageDetect_Conditions ) )
set dd.tra = TriggerAddAction ( dd.trg, function Trig_RunnerDamageLock_Actions )
set dd.tt = CreateTextTag( )
set dd.hp = 1000.00 * ChargesCount
set dd.dmg = 1.00
set dd.id = 0
set dd.time = 480
set dd.c = 0.03125
call UnitAddAbility( Runner, 'A07E' )
call UnitRemoveAbility( Runner, 'A07E' )
call UnitAddAbility( Runner, 'A08L' )
call UnitMakeAbilityPermanent( Runner, true, 'A08L' )
call SetDataBX( dd.trg, dd )
call SaveInteger( gg_htb_HashData, ExKeySoPRunner, RunnerId, dd )
call TriggerRegisterPlayerEvent( dd.trg, dd.pl, EVENT_PLAYER_LEAVE )
call TriggerRegisterDeathEvent( dd.trg, Runner )
call TriggerRegisterUnitEvent( dd.trg, Runner, EVENT_UNIT_DAMAGED )
call TriggerRegisterTimerEvent( dd.trg, 0.03125, true )
if GetLocalPlayer( ) == dd.pl or IsPlayerAlly( GetLocalPlayer( ), dd.pl ) then
call SetTextTagVisibility( dd.tt, true )
else
call SetTextTagVisibility( dd.tt, false )
endif
set pBuff = GetUnitAbility( dd.attacked, 'B00A' ) + 0x90
set dd.c = TimerGetElapsed( DispTimer )
call WMem( RMem( pBuff ) + 0x4, mR2I( dd.c + 15.10 ) )
call WMem( RMem( pBuff ) + 0x8, mR2I( dd.c + 10.408 ) )
call SetBuffLevel( pBuff - 0x90, ChargesCount )
call UpdateAirportTrainingBar( dd.tt, 100, 100 )
set Runner = null
endfunction
//===========================================================================
function InitTrig_Staff_of_Purification takes nothing returns nothing
set udg__TempBarStyle = 0
endfunction
Выше пример баффа для предмета, который образует щит блокирующий урон, кол-во заблокированного урона и сколько еще заблокирует щит отображается над головой героя, в виде полоски здоровья (только цвет сине-красный). Так же в статуе есть бафф, один в 1 как бафф дефектных способностей вара, не складывается - новый, перебивает старый. И так далее...
Пока нет желания разбираться, что у тебя так, а что не так. Но вижу, что переменная Window не назначена окну, а ещё как бы создаются в цикле одновременно 10 окон, которые потом все одновременно ждут 50 секунд. Вот скрин действий триггера вместо двух твоих, секунда ожидания поставлена для того, чтобы увидеть пропадание окна таймера.
Если еще немного покопатса на сайте в разделе декораций - можно нагрести кучу добра!
И вобще мой вам совет - научитесь минимальному моделингу: сможете клепать такие вещи за 3 минуты на коленке с необходимым вам видом, формой и текстурой.
Если еще немного покопатса на сайте в разделе декораций - можно нагрести кучу добра!
И вобще мой вам совет - научитесь минимальному моделингу: сможете клепать такие вещи за 3 минуты на коленке с необходимым вам видом, формой и текстурой.
хочешь популярности и крупный донат?? Тогда редактор варика - точно не тот инструмент для тебя. Кроме ностальгирующих ветеранов в варик никто особо не играет, а эти сами ветераны повидали всякое, едва ли ты их удивишь настолько, что о тебе будут говорить. Замечание о выходе обновления на вар3 не вызвало даже тени мысли у приятелей-некогда-перводотеров-и-кастомных-карт-игроков снова установить варкрафт(я даже не сказал им что обновление по сути ничего не делает, просто что вышло обновление). Может только мне так везёт, но мои печальные наблюдения в том, что варик медленно но верно теряет игроков.
По крайней мере слово "перспектива" тут явно чужое.
легко сделать, чего сложного то? там с зарядами итема работаешь. Нужно знать в какой момент вычитать (при событий - юнит атакован? просто юнит атакован происходит тогда, когда юнит начинает замахиваться, стрелять. )
Да, к сожалению последние дни захожу не очень часто :). У меня дочь родилась недавно, за компом вообще маловато времени теперь провожу.
По сабжу:
Там же играем, на айсикапе, только канал сменили, на AoIE, без приставки "op ".
(для перехода к нам в игре команда /join aoie в чате на любом канале)
Aws, тогда мой вариант тебе идеально подходит, осталось решить какой необратимый хеш одновременно достаточно хорош и не слишком сложен в реализации. Я помню кто-то даже md5 на jass выкладывал тут на xgm, но, имхо, это изврат.
Принцип примерно такой:
игрок вводит команду вида "-code qwerty", где code это или универсальное ключевое слово для ввода кодов или уникальное для каждого кода, в зависимости от реализации, а qwerty это ключевое слово для конкретного кода
триггер отлавливает ввод первого ключевого слова "-code" и выделяет из строки второе ключевое слово "qwerty"
ключевое слово "qwerty" прогоняется через необратимую хеш-функцию и превращается в хеш "123456"
хеш "123456" сравнивается с записаным в карте хешем, циклом если команда "-сode" универсальная, или напрямую если у каждого кода есть своя команда
если хеш совпал, то выдаем плюшки, ну а если нет, то шлем нах
при попытке вскрыть карту кулхацкер обнаружит только "-code" и "123456", но не "qwerty", а значит не сможет правильно ввести команду в официальной версии карты
наличие алгоритма хеширования в карте не спасает кулхацкера т.к. алгоритм необоратимый и не может из "123456" получить "qwerty"
кулхацкер может поробовать подобрать ключевое слово, хеш которого совпадет с "123456", но если функция хеширования достаточно хороша, то он скорее начнет рвать волосы на жопе и визжа кататься по полу, чем у него это получится
Короче, я вообще не понял ничего, вроде и на вопрос не ответили, и при этом много интересного написали. Я так понял красная цифра это урон до поглощения бронёй. Конец.
xgm.guru/p/100/192363?postid=352424#comment2с помощью приказов. Используй нктивки с имитацией' там где с магазином. Ещё нужно кучу проверок делать (есть ли ресурсы, хватает пищи и др). Вдруг пригодится
Есть две разные вещи - тренировка и покупка (найм). При тренировке ты можешь заставить здание само начать обучать войска' а вот при найме нужно чтобы к магазину подошёл юнит и он был выбран магазином (точно не уверен нужен ли здесь нацеливать выбор магазинчика, через приказ smart кажись нацеливает выборку на юнита, если правильно понял пример Warden. Приказ возвращает boolean, если что). Смотри в ссылке пример Warden-a
Понимаешь, вроде когда герой выбирает через smart магазин, у игрока на панеле по идее должны быть изображены итемы или юниты, которых продают. Вроде герой должен выбирать магазин, а не наоборот?! Странно. Хотя, попробуй ещё героем выбрать. Хотя это комп.
» WarCraft 3 / Заклинание на основе предмета
» WarCraft 3 / Мемхак 1 + Мемхак 2 = ?
» WarCraft 3 / Рандомный игрок
» WarCraft 3 / Какая версия Warcraft 3 лучше?
» WarCraft 3 / Динамический диалог
» WarCraft 3 / Управление крипами
» WarCraft 3 / Телепортация
» WarCraft 3 / JNGP не работает(
» WarCraft 3 / Панель...
» WarCraft 3 / Проблема с открытием карты
» WarCraft 3 / ИИ использование способностей
» WarCraft 3 / Помогите решить проблему с С++
» WarCraft 3 / На 90 градусов...
» WarCraft 3 / Дыхание...
» WarCraft 3 / Перестала работать инициализация
» WarCraft 3 / почему может не работать?
» WarCraft 3 / Ответе пожалуйста на несколько моих вопросов...
» WarCraft 3 / Абилка ботинка
» WarCraft 3 / Мгновенный поворот юнита
» WarCraft 3 / Вопрос по трупам
» WarCraft 3 / Проблема с таймером
» WarCraft 3 / Нужны модели
» WarCraft 3 / Про проекты
» WarCraft 3 / Инком от удара...
» WarCraft 3 / Таверна